package com.livepan.server.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.livepan.server.dao.ResourceDOMapper;
import com.livepan.server.dataobject.ResourceDO;
import com.livepan.server.dataobject.ResourceDOExample;
import com.livepan.server.error.BusinessException;
import com.livepan.server.error.EmBusinessError;
import com.livepan.server.service.model.ResourceModel;
import com.livepan.server.service.model.PageModel;
import com.livepan.server.utils.CopyUtil;
import com.livepan.server.utils.UUIDUtil;
import com.livepan.server.utils.ValidatorUtil;
import com.livepan.server.validator.ValidationResult;
import com.livepan.server.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import sun.nio.cs.CharsetMapping;


import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ResourceService {
    @Autowired
    private ResourceDOMapper resourceDOMapper;

    @Autowired
    private ValidatorImpl validator;

    public void list(PageModel pageModel) {
        PageHelper.startPage(pageModel.getPage(), pageModel.getSize());
        ResourceDOExample resourceDOExample = new ResourceDOExample();
        List<ResourceDO> resourceDOList = resourceDOMapper.selectByExample(resourceDOExample);
        PageInfo<ResourceDO> pageInfo = new PageInfo<>(resourceDOList);
        pageModel.setTotal(pageInfo.getTotal());
        List<ResourceModel> resourceModelList = resourceDOList.stream().map(
                this::convertResourceModelFromResourceDO
        ).collect(Collectors.toList());
        pageModel.setList(resourceModelList);
    }

    public void save(ResourceModel resourceModel) throws BusinessException {
        ValidationResult validateResult = validator.validate(resourceModel);
        if (validateResult.isHasError()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, validateResult.getErrMsg());
        }
        ResourceDO resourceDO = CopyUtil.copy(resourceModel, ResourceDO.class);
        if (resourceDOMapper.selectByPrimaryKey(resourceDO.getId()) == null) {
            this.insert(resourceDO);
        } else {
            this.update(resourceDO);
        }
    }

    private void insert(ResourceDO resourceDO) {
        resourceDOMapper.insertSelective(resourceDO);
    }

    private void update(ResourceDO resourceDO) {
        resourceDOMapper.updateByPrimaryKey(resourceDO);
    }

    public void delete(String id) {
        resourceDOMapper.deleteByPrimaryKey(id);
    }

    public List<ResourceModel> getAllResource() {
        ResourceDOExample resourceDOExample = new ResourceDOExample();
        resourceDOExample.setOrderByClause("id asc");
        List<ResourceDO> resourceDOList = resourceDOMapper.selectByExample(resourceDOExample);
        List<ResourceModel> resourceModelList = resourceDOList
                .stream().map(this::convertResourceModelFromResourceDO).collect(Collectors.toList());

        for (int i = resourceModelList.size() - 1; i >= 0; i--) {
            // 当前要移动的记录
            ResourceModel child = resourceModelList.get(i);

            // 如果当前节点没有父节点，则不用往下了
            if (StringUtils.isEmpty(child.getParent())) {
                continue;
            }
            // 查找父节点
            for (int j = i - 1; j >= 0; j--) {
                ResourceModel parent = resourceModelList.get(j);
                if (child.getParent().equals(parent.getId())) {
                    if (CollectionUtils.isEmpty(parent.getChildren())) {
                        parent.setChildren(new ArrayList<>());
                    }
                    // 添加到最前面，否则会变成倒序，因为循环是从后往前循环的
                    parent.getChildren().add(0, child);

                    // 子节点找到父节点后，删除列表中的子节点
                    resourceModelList.remove(child);
                }
            }
        }
        return resourceModelList;
    }

    public void saveJsonConfig(String jsonConfig) {
        List<ResourceModel> resourceModelList = JSON.parseArray(jsonConfig, ResourceModel.class);
        clear();
        for (ResourceModel resourceModel : resourceModelList) {
            resourceModel.setParent("");
            save(resourceModel);
            dfsSaveModel(resourceModel);
        }
    }

    public void clear() {
        ResourceDOExample example = new ResourceDOExample();
        resourceDOMapper.deleteByExample(example);
    }


    private ResourceModel convertResourceModelFromResourceDO(ResourceDO resourceDO) {
        if (resourceDO == null) {
            return null;
        }
        ResourceModel resourceModel = new ResourceModel();
        BeanUtils.copyProperties(resourceDO, resourceModel);
        return resourceModel;
    }

    /**
     * 自己已经保存了，只保存孩子，进行递归
     *
     * @param resourceModel
     */
    private void dfsSaveModel(ResourceModel resourceModel) {
        if (resourceModel.getChildren() == null || resourceModel.getChildren().size() == 0) {
            return;
        }
        for (ResourceModel child : resourceModel.getChildren()) {
            child.setParent(resourceModel.getId());
            save(child);
            dfsSaveModel(child);
        }
    }
}
